/*
 * This file is part of PCAPdroid.
 *
 * PCAPdroid is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * PCAPdroid is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with PCAPdroid.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Copyright 2020-21 - Emanuele Faranda
 */

package com.emanuelef.remote_capture.fragments;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.view.MenuProvider;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Lifecycle;

import com.emanuelef.remote_capture.CaptureService;
import com.emanuelef.remote_capture.ConnectionsRegister;
import com.emanuelef.remote_capture.PCAPdroid;
import com.emanuelef.remote_capture.R;
import com.emanuelef.remote_capture.Utils;
import com.emanuelef.remote_capture.activities.ConnectionsActivity;
import com.emanuelef.remote_capture.activities.MainActivity;
import com.emanuelef.remote_capture.Blacklists;
import com.emanuelef.remote_capture.model.FilterDescriptor;

public class MalwareStatusFragment extends Fragment implements MenuProvider {
    private static final String TAG = "MalwareStatus";
    private Blacklists mBlacklists;
    private Handler mHandler;
    private ImageView mStatusIcon;
    private TextView mStatus;
    private TextView mNumMalicious;
    private TextView mNumUpToDate;
    private TextView mNumChecked;
    private TextView mLastUpdate;
    private TextView mDomainRules;
    private TextView mIPRules;
    private int mOkColor, mWarnColor, mDangerColor, mTextColor, mGrayColor;

    @Override
    public View onCreateView(LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        requireActivity().addMenuProvider(this, getViewLifecycleOwner(), Lifecycle.State.RESUMED);
        return inflater.inflate(R.layout.malware_detection_status, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        Context ctx = view.getContext();

        mStatus = view.findViewById(R.id.status);
        mHandler = new Handler(Looper.getMainLooper());
        mStatusIcon = view.findViewById(R.id.status_icon);
        View mConnectionsCard = view.findViewById(R.id.show_connections);
        mNumMalicious = view.findViewById(R.id.num_malicious);
        mNumUpToDate = view.findViewById(R.id.num_up_to_date);
        mNumChecked = view.findViewById(R.id.num_checked);
        mLastUpdate = view.findViewById(R.id.last_update);
        mDomainRules = view.findViewById(R.id.num_domain_rules);
        mIPRules = view.findViewById(R.id.num_ip_rules);
        mBlacklists = PCAPdroid.getInstance().getBlacklists();
        mOkColor = ContextCompat.getColor(ctx, R.color.ok);
        mWarnColor = ContextCompat.getColor(ctx, R.color.warning);
        mDangerColor = ContextCompat.getColor(ctx, R.color.danger);
        mGrayColor = ContextCompat.getColor(ctx, R.color.lightGray);
        mTextColor = ContextCompat.getColor(ctx, R.color.highContrast);

        mConnectionsCard.setOnClickListener(v -> {
            FilterDescriptor filter = new FilterDescriptor();
            filter.onlyBlacklisted = true;

            Intent intent = new Intent(requireContext(), ConnectionsActivity.class)
                    .putExtra(ConnectionsFragment.FILTER_EXTRA, filter);
            startActivity(intent);
        });
    }

    @Override
    public void onResume() {
        super.onResume();
        updateStatus();
    }

    @Override
    public void onPause() {
        super.onPause();
        mHandler.removeCallbacksAndMessages(null);
    }

    @Override
    public void onCreateMenu(@NonNull Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.docs_menu, menu);
    }

    @Override
    public boolean onMenuItemSelected(@NonNull MenuItem item) {
        int id = item.getItemId();

        if(id == R.id.user_guide) {
            Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(MainActivity.MALWARE_DETECTION_DOCS_URL));
            Utils.startActivity(requireContext(), browserIntent);
            return true;
        }

        return false;
    }

    private void updateStatus() {
        Context ctx = requireContext();
        ConnectionsRegister reg = CaptureService.getConnsRegister();
        boolean is_running = CaptureService.isServiceActive();

        int num_malicious = ((reg != null) ? reg.getNumMaliciousConnections() : 0);
        if(num_malicious > 0) {
            mStatusIcon.setImageResource(R.drawable.ic_exclamation_triangle_solid);
            mStatusIcon.setColorFilter(mDangerColor);
            mStatus.setText(R.string.malware_status_detected);
        } else {
            if(!is_running) {
                mStatusIcon.setImageResource(R.drawable.ic_bug);
                mStatusIcon.setColorFilter(mGrayColor);
                mStatus.setText(R.string.capture_not_running_status);
            } else if(mBlacklists.isUpdateInProgress()) {
                mStatusIcon.setImageResource(R.drawable.ic_exclamation_triangle_solid);
                mStatusIcon.setColorFilter(mGrayColor);
                mStatus.setText(R.string.status_updating);
            } else if(mBlacklists.getNumUpdatedBlacklists() < mBlacklists.getNumBlacklists()) {
                mStatusIcon.setImageResource(R.drawable.ic_exclamation_triangle_solid);
                mStatusIcon.setColorFilter(mWarnColor);
                mStatus.setText(R.string.malware_status_update_failed);
            } else if(CaptureService.isDNSEncrypted()) {
                mStatusIcon.setImageResource(R.drawable.ic_exclamation_triangle_solid);
                mStatusIcon.setColorFilter(mWarnColor);
                mStatus.setText(R.string.private_dns_hinders_detection);
            } else {
                mStatusIcon.setImageResource(R.drawable.ic_check_solid);
                mStatusIcon.setColorFilter(mOkColor);
                mStatus.setText(R.string.malware_status_ok);
            }
        }

        mNumMalicious.setText(Utils.formatIntShort(num_malicious));
        if(num_malicious > 0)
            mNumMalicious.setTextColor(mDangerColor);
        else
            mNumMalicious.setTextColor(mTextColor);

        mNumUpToDate.setText(String.format(Utils.getPrimaryLocale(ctx), "%d/%d",
                mBlacklists.getNumUpdatedBlacklists(), mBlacklists.getNumBlacklists()));
        if(is_running && (mBlacklists.getNumUpdatedBlacklists() < mBlacklists.getNumBlacklists()))
            mNumUpToDate.setTextColor(mWarnColor);
        else
            mNumUpToDate.setTextColor(mTextColor);

        mNumChecked.setText(Utils.formatIntShort(CaptureService.getNumCheckedMalwareConnections()));
        mLastUpdate.setText(Utils.formatEpochMin(ctx, mBlacklists.getLastUpdate() / 1000));
        mDomainRules.setText(Utils.formatIntShort(mBlacklists.getNumLoadedDomainRules()));
        mIPRules.setText(Utils.formatIntShort(mBlacklists.getNumLoadedIPRules()));

        // Periodic update
        mHandler.postDelayed(this::updateStatus, 1000);
    }
}
